package top.qingyunge.autumn.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import top.qingyunge.autumn.annotation.DatabaseConnect;
import top.qingyunge.autumn.annotation.IgnoreToken;
import top.qingyunge.autumn.po.UserLogin;
import top.qingyunge.autumn.pojo.User;
import top.qingyunge.autumn.util.JwtUtil;
import top.qingyunge.autumn.util.PBKDF2Util;
import top.qingyunge.autumn.util.ThreadLocalUtil;
import top.qingyunge.autumn.vo.Result;
import top.qingyunge.autumn.vo.user.UserInfo;

import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.HashMap;
import java.util.Map;

import top.qingyunge.autumn.dao.UserDAO;

@Slf4j
@RestController
@RequestMapping("/user")
@DatabaseConnect("blog")
public class UserController {

    @Resource
    UserDAO userDao;

    @PostMapping("/register")
    @IgnoreToken
    @Operation(summary = "用户注册获取token")
    public Result<String> register(@RequestBody User user) throws NoSuchAlgorithmException, InvalidKeySpecException {

        if(user.getPassword() == null || user.getPassword().length() < 6) {
            return Result.error(400,"密码强度过低");
        }
        if(user.getUsername().length() > 8) {
            return Result.error(400,"用户名过长");
        }

        //    hash 、加盐
        String salt =  PBKDF2Util.generateSalt();
        String encryptedPassword = PBKDF2Util.getEncryptedPassword(user.getPassword(),salt);
        String storedPassword = encryptedPassword + salt;

        // 使用hash后的密码和盐存入用于验证
        user.setPassword(storedPassword);

        userDao.insert(user);
        Map<String,Object> map = new HashMap<>();
        map.put("username",user.getUsername());
        map.put("uid",user.getUid());
        String token = JwtUtil.getToken(map);
        return Result.success(token);
    }

    @GetMapping("/currentUser")
    @Operation(summary = "获取当前登录用户信息")
    @Parameter(name = "Authorization", in = ParameterIn.HEADER, required = true, description = "token")
    public Result<User> getCurrentUser() {
        Map<String, Object> userSession =  ThreadLocalUtil.get();
        int id = (int) userSession.get("uid");
        User user = userDao.selectById(id);
        if (user != null) {
            return Result.success(user);
        }
        return Result.error(401,"登录状态失效");
    }

    @Operation(summary = "修改用户信息")
    @PutMapping("/update")
    public Result<Boolean> updateUserInfo(@RequestBody User user) {
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("username", user.getUsername());
        updateWrapper.set("sign", user.getSign());
        updateWrapper.set("avatar", user.getAvatar());
        updateWrapper.set("email", user.getEmail());
        updateWrapper.set("phone", user.getPhone());
        updateWrapper.eq("uid", user.getUid());
        userDao.update(user, updateWrapper);
        return Result.success();
    }

    @Operation(summary = "修改密码")
    @PutMapping("/update-password")
    public Result<?> updateUserPassward(@RequestBody String oldPassword, String newPassword) throws NoSuchAlgorithmException, InvalidKeySpecException {
        Map<String, Object> userSession =  ThreadLocalUtil.get();
        int id = (int) userSession.get("uid");
        User user = userDao.selectById(id);
        // 截取存储的加密字段
        String encryptedPassword = user.getPassword().substring(0,PBKDF2Util.HASH_BIT_SIZE);
        String salt = user.getPassword().substring(PBKDF2Util.HASH_BIT_SIZE);
//        验证密码
        if(PBKDF2Util.authenticate(oldPassword,encryptedPassword,salt)) {
            //    通过后生成新密码
            String newSalt =  PBKDF2Util.generateSalt();
            String newEncryptedPassword = PBKDF2Util.getEncryptedPassword(newPassword,newSalt);
            if(newEncryptedPassword.equals(encryptedPassword)) {
                return Result.error(400,"新密码不能与原密码相同");
            }
            String newStoredPassword = newEncryptedPassword + newSalt;
            // 使用hash后的密码和盐存入用于验证
            user.setPassword(newStoredPassword);
            userDao.update(user,new UpdateWrapper<User>().set("password",newStoredPassword));
            return Result.success();
        } else  {
            return Result.error(400,"原密码错误");
        }
    }

    @IgnoreToken
    @Operation(summary = "用户登录换取token")
    @GetMapping("/login")
    public Result<UserInfo> login(@RequestBody UserLogin userLogin) throws NoSuchAlgorithmException, InvalidKeySpecException {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        User user = userDao.selectOne(queryWrapper.eq("username",userLogin.getUsername()));
        if (user == null) {
            return Result.error(400,"账号不存在");
        }
        // 截取存储的加密字段
        String encryptedPassword = user.getPassword().substring(0,PBKDF2Util.HASH_BIT_SIZE);
        String salt = user.getPassword().substring(PBKDF2Util.HASH_BIT_SIZE);
        if(PBKDF2Util.authenticate(userLogin.getPassword(),encryptedPassword,salt)) {
            Map<String,Object> map = new HashMap<>();
            map.put("username",user.getUsername());
            map.put("uid",user.getUid());
            String token = JwtUtil.getToken(map);
            UserInfo userInfo = new UserInfo();
            userInfo.setToken(token);
            userInfo.setUser(user);
            return Result.success(userInfo);
        } else  {
            return Result.error(400,"密码错误");
        }
    }
}
